package pers.rcl.common.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import pers.rcl.common.config.BodyRequestWrapper;
import pers.rcl.common.constant.CommonConstants;
import pers.rcl.common.util.SeqUtil;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Slf4j
//@Component
public class AuthFilter implements Filter {

    @Value("${ods.use.encryption}")
    protected boolean isEncryption;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;


        String id = httpRequest.getHeader("X-Request-Id");
        if (StringUtils.isBlank(id)) {
            id = SeqUtil.generateUUID();
        }
        //TODO 为每一个请求设置唯一的请求id
        MDC.put(CommonConstants.TRACE_KEY, id);
        httpResponse.addHeader("X-Request-Id", id);

        //TODO 获取请求基本信息
        String uri = httpRequest.getServletPath();
        String contentType = httpRequest.getHeader("Content-Type");
        String method = httpRequest.getMethod();
        String ip = getIpAddress(httpRequest);
        log.info("==>method:{} ==>URI:{} ==>contentType:{}==>ip:{}", method, uri, contentType, ip);


        //处理POST且为JSON格式的请求，其他请求直接放过
        boolean accept = !CommonConstants.METHOD_POST.equalsIgnoreCase(method)
                || (!contentType.contains(MediaType.APPLICATION_JSON_VALUE)
                && !contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE));

        if (accept) {
            chain.doFilter(httpRequest, httpResponse);
        } else {//JSON格式请求
            BodyRequestWrapper requestWrapper = new BodyRequestWrapper(httpRequest);

            String body = requestWrapper.getBodyString(requestWrapper);
            log.info("==>Body:{}", StringUtils.substring(body, 0, 1000));

            //TODO 对请求的数据进行自定义解析，改造后进行数据修改


            //改写请求体
            requestWrapper.setBody("解析后的参数".getBytes(StandardCharsets.UTF_8));
            chain.doFilter(requestWrapper, httpResponse);
        }
        MDC.clear();
    }

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig fConfig) {
    }

    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
